import { useState, useEffect } from 'react';
import { FolderTwoTone, FileWordTwoTone, FolderOpenTwoTone, FileAddTwoTone } from '@ant-design/icons';

import Apis from '../../api';

import styles from './post-tree.module.scss';

interface PostSummaryNode {
  title: string;
  id: number;
  type: 'S';
}

interface PostDirectoryNode {
  title: string;
  id: number;
  type: 'D';
}

type PostTreeNode = PostDirectoryNode | PostSummaryNode;

function SummaryNode({ node, onClick }: { node: PostSummaryNode; onClick: (post: PostSummaryNode) => void }) {
  return (
    <li className={styles['node']}>
      <div className={styles['title']} onClick={() => onClick(node)}>
        <span>
          <FileWordTwoTone /> {node.title}
        </span>
      </div>
    </li>
  );
}

function DirectoryNode({
  node,
  children,
  open,
  onClick,
  onSummaryClick,
}: {
  node: PostTreeNode;
  children: PostTreeNode[];
  open: boolean;
  onClick: (node: PostTreeNode) => void;
  onSummaryClick: (post: PostSummaryNode) => void;
}) {
  return (
    <li className={styles['node']}>
      <div className={styles['title']} onClick={() => onClick(node)}>
        <span>
          {open ? <FolderOpenTwoTone twoToneColor="orange" /> : <FolderTwoTone twoToneColor="orange" />} {node.title}
        </span>
        <span className={styles['title-cmd']}>
          <FileAddTwoTone />
        </span>
      </div>
      {open && <NodeList items={children} onSummaryClick={(s) => onSummaryClick(s)} />}
    </li>
  );
}

function Node({ node, onSummaryClick }: { node: PostTreeNode; onSummaryClick: (post: PostSummaryNode) => void }) {
  const [subItems, setSubItems] = useState<PostTreeNode[]>([]);
  const [itemsLoaded, setItemsLoaded] = useState<boolean>(false);
  const [open, setOpen] = useState<boolean>(false);

  switch (node.type) {
    case 'S':
      return <SummaryNode node={node} onClick={(s) => onSummaryClick(s)} />;
    case 'D': {
      const loadSubItems = (node: PostTreeNode) => {
        if (!itemsLoaded) {
          Apis.Post.getSubTreeItems(node.id)
            .then((treeNodes) => {
              setItemsLoaded(true);
              setOpen(true);
              setSubItems(treeNodes as PostTreeNode[]);
            })
            .catch((err) => console.error('TODO:', err));
        } else {
          setOpen(!open);
        }
      };
      return (
        <DirectoryNode
          node={node}
          open={open}
          children={subItems}
          onClick={loadSubItems}
          onSummaryClick={(s) => onSummaryClick(s)}
        />
      );
    }
    default:
      console.error('unknown node type ', node);
      return null;
  }
}

function NodeList({
  items,
  onSummaryClick,
}: {
  items: PostTreeNode[];
  onSummaryClick: (post: PostSummaryNode) => void;
}) {
  return (
    <ul style={{ listStyle: 'none', paddingLeft: 0 }}>
      {items.map((it) => (
        <Node key={it.id} node={it} onSummaryClick={(s) => onSummaryClick(s)} />
      ))}
    </ul>
  );
}

export function PostTree({
  rootId,
  onSummaryClick,
}: {
  rootId: number;
  onSummaryClick: (post: PostSummaryNode) => void;
}) {
  const [treeNodes, setTreeNodes] = useState<PostTreeNode[]>([]);

  useEffect(() => {
    Apis.Post.getSubTreeItems(rootId)
      .then((treeNodes) => setTreeNodes(treeNodes as PostTreeNode[]))
      .catch((err) => console.error('TODO:', err));
  }, [rootId]);

  return (
    <div>
      <NodeList items={treeNodes} onSummaryClick={(s) => onSummaryClick(s)} />
    </div>
  );
}
